<?php

namespace App\Admin\Services;

use App\Admin\Traits\RouteHelper;
use App\Models\AdminMenu;
use App\Models\AdminUser;
use Cache;

class MenuService
{
    use RouteHelper;

    const CACHE_PREFIX     = 'admin:menus:';
    const CACHE_EXPIRED_AT = 60; // 60 minutes

    protected $roleMenu;

    /**
     * 獲取指定/全部菜單集合
     * @param array  $id
     * @param string $limit
     * @return \App\Models\AdminMenu[]|\Illuminate\Contracts\Pagination\LengthAwarePaginator|\Illuminate\Database\Eloquent\Collection|\Illuminate\Support\Collection
     */
    public function getMenus($id = [], $limit = '')
    {
        if ($limit) {
            // 需要分頁返回
            return AdminMenu::orderBy('sort', 'asc')
                ->orderBy('id', 'asc')
                ->paginate($limit);
        }
        if (!empty($id) && !is_array($id)) {
            $id = [$id];
            return AdminMenu::whereIn('id', $id)
                ->orderBy('sort', 'asc')
                ->orderBy('id', 'asc')
                ->get();
        }
        return AdminMenu::all();
    }

    /**
     * 獲取菜單樹結構套嵌數組
     * @return mixed
     */
    public function getMenusTree()
    {
        return (new AdminMenu)->setOrderColumn('sort asc, id asc')->toTree();
    }

    /**
     * @param $id
     * @return mixed
     */
    public function findMenu($id)
    {
        return AdminMenu::find($id);
    }

    /**
     * @param $request
     */
    public function store($request)
    {
        $request['sort'] = $request['sort'] ?? 0;
        return (new AdminMenu)->fill($request)->save();
    }

    /**
     * update
     */
    public function update($request)
    {
        $request['sort'] = $request['sort'] ?? 0;
        return AdminMenu::find($request['id'])->fill($request)->save();
    }

    /**
     * delete
     */
    public function delete($id)
    {
        if (empty($id)) {
            return;
        }
        $id = (array)$id;
        AdminMenu::destroy($id);
        return AdminMenu::whereIn('parent_id', $id)->delete();
    }

    /**
     * 獲取前台菜單-排除沒有權限的路由
     * @param $adminId
     * @return mixed
     */
    public function getAdminMenus($adminId)
    {
        if (empty($adminId)) {
            return [];
        }

        return Cache::remember(self::CACHE_PREFIX . $adminId, self::CACHE_EXPIRED_AT, function () {
            // 獲取整顆樹
            $trees = (new AdminMenu)->setOrderColumn('sort asc, id asc')->toTree();

            // 獲取用戶擁有的所有路由進行對比
            $routes = $this->getHasRoutes();
            if (in_array('*', $routes)) {
                return $trees;
            }

            // 去除ret中沒有的權限訪問的路徑
            foreach ($trees as $key => $tree) {
                foreach ($tree['childrens'] ?? [] as $k => $v) {
                    // 轉換uri的格式和權限的路由保持統一
                    $compare_uri = 'GET:' . substr($v['uri'] == '/' ? '//' : $v['uri'], 1);
                    if (!in_array($compare_uri, $routes)) {
                        unset($trees[$key]['childrens'][$k]);
                    }
                }
                // 如果子節點被清空,同時清空父節點
                if (empty($trees[$key]['childrens'])) {
                    unset($trees[$key]);
                }
            }
            return $trees;
        });
    }

    public static function refreshAdminMenus()
    {
        AdminUser::get()->map(function ($item, $key) {
            Cache::forget(self::CACHE_PREFIX . $item->id);
        });
    }
}
